/**
 * Created by jinxs on 14-7-4.
 *依赖
 * ui.mask.js
 * ui.loading.js
 * ui.position.js
 * ui.panel.js
 */
(function ($) {
    /**
     * 缓存名称
     * @type {string}
     * @private
     */
    var _cacheName = 'uiGrid';
    var _idFieldName = 'idField';

    /**
     * @class 表单－基类
     * @requires {@link panel}
     * @constructor uiGrid
     * @summary 构造函数
     * @param [options] {Object|String} 组件配置参数|要调用的组件方法名
     * @param [param] {Object} 表示要调用的组件方法的参数
     * @example
     * // 构件组件
     * $('#selectAge').uiGrid({direction: 'left'});
     * // 调用组件方法options
     * $('#selectAge').uiGrid("options");
     */
    $.fn.uiGrid = function (options, param) {
        if (this.length > 0 && typeof options == 'string') {
            return $.fn.uiGrid.methods[options](this.first(), param);
        }
        return this.each(function () {
            var me = $(this);
            var cache = me.data(_cacheName);

            options = options || {};
            if (cache) {
                $.extend(cache.options, options);
            } else {
                var opts = $.extend(true, {}, $.fn.uiGrid.defaults, me.parseUIConfig(), options);
                me.data(_cacheName, {options: opts});
            }
            _init(me);
        });
    };
    /**
     * 方法
     * @lends uiGrid.prototype
     */
    $.fn.uiGrid.methods = {
        /**
         * @summary 获取所有配置
         * @name uiGrid#options
         * @function
         * @param target {jQuery}
         * @returns {*|Function|HTMLOptionsCollection|options|options}
         */
        options: function (target) {
            return $.data(target[0], _cacheName).options;
        }
        /**
         * @summary 获取grid的数据源
         * @name uiGrid#gridData
         * @function
         * @param target {jQuery}
         * @returns {*|Function|HTMLOptionsCollection|options|options}
         */
        , gridData: function (target) {
            return $.data(target[0], _cacheName).options.gridData;
        }
        /**
         * @summary 加载数据
         * @name uiGrid#loadData
         * @function
         * @param target {jQuery}
         * @param opts {String}
         * @returns {Array}
         */
        , loadData: function (target, opts) {
            var options = $.data(target[0], _cacheName).options;
            $.extend(true, options, opts);
            var palContent = target.uiPanel('content');
            var grid_data = palContent.children('.grid_data');
            _renderGridBody(target, palContent, grid_data);
        }
        /**
         * @summary 设置数据并加载
         * @name uiGrid#setData
         * @function
         * @param target {jQuery}
         * @param data {String}
         * @returns {jQuery} target
         */
        , setData: function (target, data) {
            var palContent = target.uiPanel('content');
            var grid_data = palContent.children('.grid_data');

            _getData(target, palContent, grid_data, data);
            return target;
        }
        /**
         * @summary获取工具栏
         * @name uiGrid#toolbar
         * @function
         * @param target {jQuery}
         * @param opts {String}
         * @returns {Array}
         */
        , toolbar: function (target) {
            var palContent = target.uiPanel('content');
            return palContent.children('.grid_toolbar');
        }
        /**
         * @summary 获取已选择的数据信息
         * @name uiGrid#selectedData
         * @function
         * @param target {jQuery}
         * @param field {String} 用于筛选要返回的字段名
         * @returns {Array}
         */
        , selectedData: function (target, field) {
            var options = target.data(_cacheName).options;
            var selectedRows = options._selectedRows;
            var cacheData = options._cacheData.rows;
            var data = [];

            if (selectedRows.length > 0) {
                $.each(selectedRows, function (i, n) {
                    if (!field) {
                        data[i] = cacheData[n];
                    }
                    else {
                        data[i] = cacheData[n][field];
                    }
                });
            }
            return data;
        }
        /**
         * @summary 获取表格指定列的样式定义
         * @name uiGrid#getColumnStyle
         * @function
         * @param target {jQuery}
         * @param columnIndex {Number} 指定列，从0开始
         * @returns {CSSStyleDeclaration} 表格指定列的样式定义或null
         */
        , getColumnStyle: function (target, columnIndex) {
            var options = target.data(_cacheName).options;

            return options._colStyles[columnIndex];
        }
    };
    /**
     * 默认配置
     * @lends uiGrid.prototype
     */
    $.fn.uiGrid.defaults = {
        /**
         * @type Boolean
         * @default false
         * @summary 指示组件是否只设置样式(应用于已经生成好数据表的情况)
         */
        onlyStyle: false,
        /**
         * @type Boolean
         * @default false
         * @summary 指示组件是否自动适应
         */
        autoFit: false,
        /**
         * 表格的列宽在初始化时会根据内容进行计算（除非在表头的列指定了固定宽度，
         * 此时若该列包含样式auto-width，则固定宽度可以为百分比且该列的宽度会再根据表格整体宽度进行比例缩放）。
         * @type Boolean
         * @default false
         * @summary 指示表格列宽是否适应
         */
        colFit: false,
        /**
         * @type Boolean
         * @default false
         * @summary 指示表格列宽是否一直适应
         */
        colFitAllTime: false,
        /**
         * @type Boolean
         * @default false
         * @summary 指示表格标题是否固定
         */
        gridTitleFix: false,
        /**
         * @type Boolean
         * @default true
         * @summary 指示组件是否显示边框
         */
        border: true,
        /**
         * @type String
         * @default ""
         * @summary 指示组件图标
         */
        icon: '',
        /**
         * @type String
         * @default ""
         * @summary 指示组件标题
         */
        title: '',
        /**
         * @type Number
         * @default 400
         * @summary 指示组件宽度
         */
        width: 0,
        /**
         * @type Number
         * @default 300
         * @summary 指示组件高度
         */
        height: 0,
        /**
         * @type Boolean
         * @default true
         * @summary 指示组件是否显示标题栏
         */
        showHeader: true,
        /**
         * @type String
         * @default ""
         * @summary 为组件加载的提示信息
         */
        loadMsg: '',
        /**
         * @type String
         * @default null
         * @summary 为组件加载数据
         */
        localData: null,
        /**
         * @type Boolean
         * @default false
         * @summary 是否延迟加载远程数据
         */
        lazyLoad: false,
        /**
         * @type String
         * @default id
         * @summary 指示组件信息主键的字段名
         */
        idField: 'id',
        /**
         * 可选值有get, post
         * @type String
         * @default "post"
         * @summary 向指定的url请求数据时使用的方法
         */
        method: 'get',
        /**
         * @type String
         * @default ""
         * @summary 指定远程数据加载的url
         */
        url: '',

        tpl_head: '',

        tpl_body: '',
        /**
         * @type Object
         * @default {}
         * @summary 指示组件的请求参数
         */
        queryParams: {},
        defaultSortField:'',
        defaultOrder:'desc',
        paramSort:'orderField',
        paramOrder:'descended',
        paramPageIndex:'pageIndex',
        paramPageSize:'pageSize',
        /**
         * @type Number
         * @default 1
         * @summary 指示组件是的起始页
         */
        pageIndex: 1,
        /**
         * @type Number
         * @default 20
         * @summary 指示组件的页面大小
         */
        pageSize: 20,
        /**
         * @type Array
         * @default [20, 40, 50, 100, 200]
         * @summary 指示组件的页面大小选择项
         */
        pageList: [20, 40, 50, 100, 200],
        /**
         * @summary 在行选择时触发的方法。
         * @event
         * @name uiGrid#onSelectRow
         * @this 组件jQuery对象
         * @default null
         */
        onSelectRow: function (selectedIndexs, selectedIds) {
        },
        /**
         * @type Boolean
         * @default false
         * @summary 加载数据时是否自动选择上一次选中的行
         */
        autoSelectedOnLoad: false,
        /**
         * @type Boolean
         * @default true
         * @summary 指示组件是否支持行多选
         */
        multiSelect: true,

        /**
         * @type Boolean
         * @default true
         * @summary 指示组件的列是否可调整大小
         */
        colResizable: true,
        /**
         * @type Number
         * @default 0
         * @summary 指示组件的最小列宽
         */
        minColWidth: 0,
        /**
         * @type Number
         * @default 1000
         * @summary 指示组件的最大列宽
         */
        maxColWidth: 1000,
        /**
         * @type Boolean
         * @default true
         * @summary 指示数据加载完全时组件是否可本地排序
         */
        localSortable: false,
        _cacheData: {},
        _selectedRows: [],
        _colStyles: [],
        selectedIds: [],
        /**
         * @event
         * @name uiGrid#dataFilter
         * @type function
         * @default function () { return data;}
         * @summary 数据过滤
         */
        dataFilter:function(data){
          return data;
        },
        /**
         * @event
         * @name uiGrid#onBeforeLoad
         * @type function
         * @default function () { }
         * @summary 设置组件加载数据之前的事件
         */
        onBeforeLoadData: function () {
        }
        /**
         * @event
         * @name uiGrid#onLoadError
         * @type function
         * @default function () { }
         * @summary 设置组件加载数据失败的事件
         */
        , onLoadDataError: function () {
        }
        /**
         * @event
         * @name uiGrid#onLoadComplete
         * @type function
         * @default function () { }
         * @summary 设置组件加载数据完成的事件
         */
        , onLoadDataSuccess: function (result) {
        }
    };
//////--------------------------------内部方法------------------------------
    /**
     * 初始化
     * @param target 目标对象
     */
    var _init = function (target) {
        var options = target.data(_cacheName).options;
        target.addClass('grid');
        var onlyStyle = options.onlyStyle;
        var grid_data = target.children('table.grid_data').wrap('<div class="grid_data"></div>').parent();
        var content;
        var palContent;

        grid_data.find('tbody tr:first-child').children().each(function (i) {
            $(this).addClass('col_' + i);
        });
        options.tpl_head = $('thead', grid_data).html();
        options.tpl_body = $('tbody', grid_data).html();
        grid_data.empty();
        content = target.children().detach();
        target.uiPanel({
            autoFit: options.autoFit,
            icon: options.icon,
            title: options.title,
            width: options.width,
            height: options.height,
            border: options.border,
            minWidth: 0,
            minHeight: 0,
            showHeader: options.showHeader,
            showBtnBar: false
        });
        palContent = target.uiPanel('content').append(content);
        $.uiLoading.add({
            container: palContent,
            text: options.loadMsg || $.uiLoading.defaults.text
        });

        if (!onlyStyle) {
            _renderTpl(target);
        }
        _renderToolbar(palContent);
        _renderPagination(target, palContent, grid_data);
        _renderGridStyle(target, grid_data);
        _gridFit(target, grid_data);
        _renderGridBody(target, palContent, grid_data, true);
        target.bind('_resize', function () {
            var me = $(this);
            target.uiPanel('resize');
            var gridData = me.find('div.grid_data');
            _gridFit(me, gridData);
            _renderView(me, gridData, me.data(_cacheName).options.colFitAllTime);
        });
        return target;
    };
    var _renderTpl = function (target) {
        var options = target.data(_cacheName).options;
        options.tpl_body = '{{each rows as value i}}' + options.tpl_body + '{{/each}}';
        options._tplBodyFn = template.compile(options.tpl_body);
    };
    /**
     * 渲染grid的标题
     * @param target
     * @param grid_data
     * @private
     */
    var _renderGridStyle = function (target, grid_data) {
        var options = $.data(target[0], _cacheName).options;
        var onlyStyle = options.onlyStyle;
        if (options.gridTitleFix) {
            var gridHeader = $('<div class="ui_grid_head"><div class="ui_grid_head1"><table  class="ui_grid"><thead>' + options.tpl_head + '</thead></table></div></div>');
            var gridBody = $('<div class="ui_grid_data"><div class="ui_grid_data1"><table class="ui_grid"><tbody>' + (onlyStyle ? options.tpl_body : '') + '</tbody></table></div></div>');
            var tmpScrollTop;

            gridHeader.appendTo(grid_data);
            gridBody.appendTo(grid_data);
            tmpScrollTop = gridBody.scrollTop();
            gridBody.unbind('scroll').bind('scroll', function () {
                //防止垂直滚动时计算
                if (tmpScrollTop != gridBody.scrollTop()) {
                    tmpScrollTop = gridBody.scrollTop();
                    return;
                }
                gridHeader.scrollLeft(gridBody.scrollLeft());
            });
        } else {
            var table = $('<table  class="ui_grid"><thead>' + options.tpl_head + '</thead><tbody></tbody></table>');
            table.appendTo(grid_data);
            table.find('thead tr:last-child td').addClass('ui_grid_head_border');
            if (options.colFit) {
                table.css('width', '98%');
            }
            grid_data.css('overflow', 'auto');
        }
    };
    var _renderGridBody = function (target, palContent, grid_data, isInit) {
        var options = $.data(target[0], _cacheName).options;

        if (options.onlyStyle) {
            _renderView(target, grid_data);
            return;
        }
        if (options.localData) {
            options.onBeforeLoadData.call(target);
            options.gridData = options.dataFilter.call(target,options.localData);
            _getData(target, palContent, grid_data, options.gridData);
            options.onLoadDataSuccess.call(target, options.gridData);
        } else if (!isInit || !options.lazyLoad) {
            if (options.url != '') {
                var pagination = palContent.find('.grid_pagination');
                var ajaxData = options.queryParams;

                if(options.defaultSortField && !ajaxData[options.paramSort]){
                    ajaxData[options.paramSort] = options.defaultSortField;
                    ajaxData[options.paramOrder] = options.defaultOrder=='desc';
                }
                if (pagination.length > 0) {
                    var obj = {};
                    obj[options.paramPageIndex] = options.pageIndex;
                    obj[options.paramPageSize] = options.pageSize;
                    $.extend(ajaxData, obj);
                }
                $.ajax({
                    type: options.method,
                    url: options.url,
                    cache: false,
                    showLoading:false,
                    data: ajaxData,
                    dataType: "json",
                    beforeSend: function () {
                        if (options.showLoading) {
                            $.uiLoading.show({
                                container: palContent
                            });
                        }
                        options.onBeforeLoadData.call(target);
                    },
                    success: function (result) {
                        if (result.success) {
                            options.gridData =options.dataFilter.call(target, result.data);
                            _getData(target, palContent, grid_data, options.gridData);
                            options.onLoadDataSuccess.call(target, options.gridData);
                            return false;
                        }
                    },
                    complete: function () {
                        if (options.showLoading) {
                            $.uiLoading.hide({container: palContent});
                        }
                    },
                    error: function () {
                        options.onLoadDataError.call(target, arguments);
                        alert('加载远程数据' + options.url + '失败！');
                        return false;
                    }
                });
            }
        }
    };
    var _getData = function (target, palContent, grid_data, data) {
        var options = target.data(_cacheName).options;
        var dataHtml, tbody;
        var pagination = palContent.find('.grid_pagination');
        if (pagination.length > 0) {
            pagination.uiPagination('refresh', $.extend(options,{total: data.total}));
        }
        options._cacheData = data;
        options._selectedRows = [];
        target.find('thead :checkbox.grid_selector').each(function () {
            this.checked = false;
        });
        dataHtml = $(options._tplBodyFn(data));
        if (options.gridTitleFix) {
            tbody = grid_data.find('div.ui_grid_data table.ui_grid tbody');
        } else {
            tbody = grid_data.find('table.ui_grid tbody');
        }
        tbody.html(dataHtml);
        _renderView(target, grid_data);
        _renderSelection(target, tbody);
    };

    var _gridFit = function (target, grid_data) {
        var options = $.data(target[0], _cacheName).options;
        var size = grid_data.autoFit(true, false);
        if (options.gridTitleFix) {
            grid_data.find('div.ui_grid_data').autoFit(true, false, true, '.ui_grid_head');
        }
    };
    /**
     *
     * @param target
     * @param grid_data
     * @param resetWidth 是否重新计算列宽
     * @private
     */
    var _renderView = function (target, grid_data, resetWidth) {
        var options = target.data(_cacheName).options;
        var gridHeader = grid_data.children('div.ui_grid_head');
        var headTable = gridHeader.find('.ui_grid');
        var headTrs_last_tds = headTable.find('tr:last-child td');
        var targetId = target.attr('id');
        var colStyles = options._colStyles;
        var colWidths = options._colWidths;
        var inited = colStyles.length > 0;

        if (!inited) {
            resetWidth = true;
            colStyles = options._colStyles = [];
            colWidths = options._colWidths = [];
            // ##colresizer
            if (options.colResizable) {
                $('<div class="resizer"></div>').setIDByParentID(targetId, $.uiTemplate.uiGrid.colresizer).appendTo(grid_data);
            }
            // #colresizer
            // ##grid_sort
            if (headTrs_last_tds.length == 0) {
                headTrs_last_tds = grid_data.find('thead tr:last-child td');
            }
            headTrs_last_tds.each(function () {
                var td = $(this);
                if (td.attr('sortfield')) {
                    var div = td.children('div');
                    if (div.length > 0) {
                        div.addClass('icon_sort');
                    }
                    else {
                        td.wrapInner('<div class="icon_sort"></div>');
                    }
                    td.addClass('sortable').click(function () {
                        var opt = $('#' + targetId).data(_cacheName).options;
                        var data = opt.localData || opt._cacheData;
                        var me = $(this);
                        var sort = me.attr('sortfield');
                        var order = 'asc';
                        if (me.hasClass('asc')) {
                            order = 'desc';
                            me.removeClass('asc').addClass(order);
                        }
                        else if (me.hasClass('desc')) {
                            if(opt.defaultSortField){
                                sort = opt.defaultSortField;
                                order = opt.defaultOrder;
                            }
                            else {
                                order = '';
                            }
                            me.removeClass('desc');
                        }
                        else {
                            me.addClass(order).siblings('.asc,.desc').removeClass('asc desc');
                        }
                        if (order == '') {
                            delete opt.queryParams[opt.paramSort];
                            delete opt.queryParams[opt.paramOrder];
                        }
                        else {
                            opt.queryParams[opt.paramSort] = sort;
                            opt.queryParams[opt.paramOrder] = order=='desc';
                        }
                        if (!!opt.localData || (opt.localSortable && data.total == data.rows.length)) {
                            if (order == '' || data._sorted) {
                                var tmp = data.rows;
                                data.rows = data._rows;
                                data._rows = tmp;
                                data._sorted = !data._sorted;
                            }
                            if (order != '') {
                                if (!data._rows) {
                                    data._rows = $.map(data.rows, function (a) {
                                        return a;
                                    });
                                }
                                data.rows.sort(function (a, b) {
                                    var v1 = a[sort] || '';
                                    var v2 = b[sort] || '';
                                    var c = 0;

                                    if (typeof v1 === 'number') {
                                        c = v1 - v2;
                                    }
                                    else {
                                        c = v1.localeCompare(v2);
                                    }
                                    return order == 'asc' ? c : -c;
                                });
                            }
                            _getData(target, target.uiPanel('content'), grid_data, data);
                        }
                        else {
                            _renderGridBody(target, target.uiPanel('content'), grid_data);
                        }
                    });
                }
            });
            // #grid_sort
        }
        if (options.gridTitleFix && resetWidth === true) {
            var gridBody = grid_data.children('div.ui_grid_data');
            var bodyTable = gridBody.find('.ui_grid');
            var trs = bodyTable.children().children();
            if (trs.length > 0) {
                var bodytd = trs.eq(0).children();
                var tableWidth = 0;
                var staticWidth = 0;
                var padWidth = bodytd.outerWidth() - bodytd.width();
                var fitCols = [];
                var gridWidth = grid_data.width() - 21;

                bodytd.each(function (index) {
                    var me = $(this);
                    var td = headTrs_last_tds.eq(index);
                    var maxWidth = 0;
                    var isFixed;

                    if (!inited) {
                        isFixed = !td.hasClass('auto-width') && !!td[0].style.width;
                        // ##colresizer
                        if (options.colResizable) {
                            td.resizable({
                                handles: 'e',
                                minWidth: options.minColWidth,
                                maxWidth: options.maxColWidth,
                                onStartResize: function (e) {
                                    var resizer = $.getByParentID(targetId, $.uiTemplate.uiGrid.colresizer);
                                    var dl = resizer.parent().offset().left;
                                    resizer.css('left', e.pageX - dl).show();
                                    return false;
                                },
                                onResize: function (e) {
                                    var resizer = $.getByParentID(targetId, $.uiTemplate.uiGrid.colresizer);
                                    var dl = resizer.parent().offset().left;
                                    resizer.css('left', e.pageX - dl);
                                    return false;
                                },
                                onStopResize: function (e) {
                                    var cw = e.data.width - e.data.startWidth;
                                    if (cw != 0) {
                                        var opt = $('#' + targetId).data(_cacheName).options;
                                        var colWidths = opt._colWidths;
                                        var idx = this.index();

                                        if (opt.colFitAllTime) {
                                            var tw = 0;
                                            $.each(colWidths, function (i, n) {
                                                tw += n;
                                            });
                                            cw = Math.floor(cw * tw / (this.parent().width()));
                                        }
                                        colWidths[idx] += cw;
                                        if (colWidths[idx] < 0) {
                                            colWidths[idx] = 0;
                                        }
                                        _renderView(target, grid_data, true);
                                    }
                                    $.getByParentID(targetId, $.uiTemplate.uiGrid.colresizer).hide();
                                    return false;
                                }
                            });
                        }
                        // #colresizer
                        if (!isFixed) {
                            maxWidth = Math.max(td.width(), td.hasClass('auto-width')?0:me.width());
                            if (!options.colFit) {
                                colStyles[index] = $.globalCSS('#' + targetId + ' .col_' + index, 'width:' + maxWidth + 'px;');
                            }
                        }
                        else {
                            maxWidth = parseFloat(td[0].style.width);
                            td.addClass('fixed-width');
                            colStyles[index] = $.globalCSS('#' + targetId + ' .col_' + index, 'width:' + maxWidth+'px');
                        }
                        colWidths[index] = maxWidth;
                        td.addClass('col_' + index).css('width', '');
                    }
                    else {
                        isFixed = td.hasClass('fixed-width');
                        maxWidth = colWidths[index];
                        if (isFixed || !options.colFitAllTime) {
                            colStyles[index].style.width = maxWidth + 'px';
                        }
                    }
                    tableWidth += maxWidth + padWidth;
                    if (isFixed) {
                        staticWidth += maxWidth + padWidth;
                    }
                    else if ((!inited && options.colFit) || options.colFitAllTime) {
                        fitCols[fitCols.length] = {index: index, width: maxWidth};
                    }
                });
                if ((!inited && options.colFit) || options.colFitAllTime) {
                    var ext = gridWidth - staticWidth;
                    var pct = (tableWidth - staticWidth) / ext;
                    for (var i = 0; i < fitCols.length; i++) {
                        var index = fitCols[i].index;
                        var w = Math.floor((fitCols[i].width + padWidth) / pct);
                        ext -= w;
                        staticWidth += w;
                        w -= padWidth;
                        if (i == fitCols.length - 1) {
                            w += ext;
                            staticWidth += ext;
                        }
                        if (!inited) {
                            colStyles[index] = $.globalCSS('#' + targetId + ' .col_' + index, 'width:' + w + 'px;');
                            if (!options.colFitAllTime) {
                                colWidths[index] = w;
                            }
                        }
                        else if (w > 0) {
                            colStyles[index].style.width = w + 'px';
                        }
                    }
                    tableWidth = gridWidth;
                }
                gridHeader.children('.ui_grid_head1').width(tableWidth + 21);
                gridBody.children().width(tableWidth);
                if (!inited) {
                    headTable.css('table-layout', 'fixed');
                    bodyTable.css('table-layout', 'fixed');
                }
                headTable.width(tableWidth);
                bodyTable.width(tableWidth);
            }
        }
    };
    var _renderSelection = function (target, gridTBody) {
        var cks = gridTBody.find(':checkbox.grid_selector'),
            targetId = target.attr('id'),
            options = target.data(_cacheName).options,
            selectedRows = options._selectedRows,
            onSelectRow = options.onSelectRow,
            selectedIds = options.selectedIds,
            autoSelect = options.autoSelectedOnLoad,
            fn = function (e) {
                var ck = $(this),
                    tr = ck,
                    isTr = !ck.is(':checkbox'),
                    ckAll = tr.closest('div.grid_data').find('thead :checkbox.grid_selector');
                if (!isTr) {
                    tr = ck.closest('tr');
                }
                else {
                    ck = tr.find(':checkbox.grid_selector');
                }
                if (!options.multiSelect || (isTr && !e.ctrlKey)) {
                    tr.siblings('.selected').removeClass('selected')
                        .find(':checked.grid_selector').each(function () {
                            this.checked = false;
                        });
                }
                if (!isTr || e.ctrlKey) {
                    var cked = false;
                    cked = tr.hasClass('selected');
                    tr.toggleClass('selected', !cked);
                    ck[0].checked = !cked;
                }
                else {
                    ck[0].checked = true;
                    tr.addClass('selected');
                }
                selectedRows.splice(0, selectedRows.length);
                selectedIds.splice(0, selectedIds.length);
                tr.parent().children().each(function (i) {
                    if (!$(this).hasClass('selected')) {
                        cked = false;
                    }
                    else {
                        selectedRows[selectedRows.length] = i;
                        if (autoSelect&&tr.attr('idField')) {
                            selectedIds[selectedIds.length] = tr.attr('idField');
                        }
                    }
                });
                ckAll.each(function () {
                    this.checked = cked;
                    cked = null;
                });
                if (typeof onSelectRow === 'function') {
                    onSelectRow.call(target, selectedRows, selectedIds);
                }
                if (isTr && e.ctrlKey) {
                    return false;
                }
            };
        cks.each(function(index, ck) {
            var me = $(ck);
            var tr = me.closest('tr');
            me.change(fn).mousedown(function () {
                return false;
            });
            tr.mousedown(fn);
            if (autoSelect) {
                var val = tr.attr(_idFieldName);
                if (val) {
                    for (var i = 0; i < selectedIds.length; i++) {
                        if (val == selectedIds[i]) {
                            selectedRows[selectedRows.length] = index;
                            selectedIds.splice(0,0,selectedIds[i++]);
                            tr.addClass('selected');
                            ck.checked = true;
                        }
                    }
                }
            }
        });
        if (autoSelect) {
            if(selectedIds.length > 0){
                //selectedIds.splice(selectedRows.length, selectedIds.length - selectedRows.length);
                selectedIds.length = selectedRows.length;
            }
            if(typeof onSelectRow === 'function') {
                onSelectRow.call(target, selectedRows, selectedIds);
            }
        }
        target.find('thead :checkbox.grid_selector').unbind('change').change(function () {
            var me = $(this),
                grid = $('#' + targetId),
                cked = this.checked,
                opt = grid.data(_cacheName).options,
                trs = me.closest('div.grid_data').find('table tbody tr');
            if (!opt.multiSelect) {
                return false;
            }
            selectedRows.splice(0, selectedRows.length);
            selectedIds.splice(0, selectedIds.length);
            var j=0;
            trs.each(function (i) {
                var tr = $(this);
               var ckCount = tr.find("input.grid_selector").length;
               if(ckCount>0) {
                   if (cked) {
                       selectedRows[j] = i;
                       j++;
                       if (opt.autoSelectedOnLoad) {
                           selectedIds[selectedIds.length] = tr.attr('idField');
                       }
                   }
                   tr.toggleClass('selected', cked).find(':checkbox.grid_selector').each(function () {
                       this.checked = cked;
                   });
               }
            });
            if (typeof onSelectRow === 'function') {
                onSelectRow.call(grid, selectedRows, selectedIds);
            }
        });
    };
    var _renderToolbar = function (palContent) {
        var toolbar = palContent.children('.grid_toolbar');
        if (toolbar.length > 0) {
            toolbar.uiButtonBar();
            toolbar.css('marginLeft', -1);
        }
    };
    var _renderPagination = function (target, palContent, grid_data) {
        var pagination = palContent.find('.grid_pagination');
        if (pagination.length > 0) {
            var options = $.data(target[0], _cacheName).options;
            pagination.uiPagination({
                pageIndex: options.pageIndex,
                pageSize: options.pageSize,
                pageList: options.pageList,
                onSelectPage: function (pageIndex, pageSize) {
                    options = $.data(target[0], _cacheName).options;
                    options.pageIndex = pageIndex;
                    options.pageSize = pageSize;
                    _renderGridBody(target, palContent, grid_data);
                },
                onChangePageSize: function (pageSize) {
                    options = $.data(target[0], _cacheName).options;
                    options.pageIndex = 1;
                    options.pageSize = pageSize;
                    _renderGridBody(target, palContent, grid_data);
                }
            });
        }
    };
})(jQuery);
